/**
 * MongoDB 服务类
 * 提供数据操作方法，符合现有项目风格
 */

import { 
  User, 
  WxUser,
  WxRefreshToken,
  OCRRecord, 
  MedicalAlert, 
  SystemLog, 
  MedicalEquipment, 
  DrugInfo,
  IUser,
  IWxUser,
  IWxRefreshToken,
  IOCRRecord,
  IMedicalAlert,
  ISystemLog,
  IMedicalEquipment,
  IDrugInfo,
  IPatient,
  Patient
} from '../models/mongodb-schemas';

export class MongoDBService {
  
  // ========== 用户管理 ==========
  
  /**
   * 创建用户
   */
  async createUser(userData: Partial<IUser>): Promise<IUser> {
    const user = new User(userData);
    return await user.save();
  }

  /**
   * 根据用户名获取用户
   */
  async getUserByUsername(username: string): Promise<IUser | null> {
    return await User.findOne({ username });
  }

  /**
   * 根据邮箱获取用户
   */
  async getUserByEmail(email: string): Promise<IUser | null> {
    return await User.findOne({ email });
  }

  /**
   * 根据用户ID获取用户
   */
  async getUserById(userId: string): Promise<IUser | null> {
    return await User.findOne({ userId });
  }

  /**
   * 根据人脸哈希获取用户
   */
  async getUserByFaceHash(faceHash: string): Promise<IUser | null> {
    return await User.findOne({ 'faceData.hash': faceHash });
  }

  /**
   * 更新用户人脸数据
   */
  async updateUserFaceData(userId: string, faceData: { hash: string; timestamp: Date }): Promise<IUser | null> {
    return await User.findOneAndUpdate(
      { userId },
      { 
        hasFace: true,
        faceData 
      },
      { new: true }
    );
  }

  /**
   * 获取所有用户
   */
  async getAllUsers(): Promise<IUser[]> {
    return await User.find({}).select('-password');
  }

  /**
   * 更新用户信息
   */
  async updateUser(userId: string, updateData: Partial<IUser>): Promise<IUser | null> {
    return await User.findOneAndUpdate(
      { userId },
      updateData,
      { new: true }
    );
  }

  // ========== wxapp 用户管理 ==========

  /**
   * 创建wxapp用户
   */
  async createWxUser(userData: Partial<IWxUser>): Promise<IWxUser> {
    const sanitized: Partial<IWxUser> = { ...userData };
    // 避免写入 phone: null/空串
    if (sanitized && ('phone' in sanitized)) {
      const value = (sanitized as any).phone;
      if (value === null || value === undefined || (typeof value === 'string' && value.trim() === '')) {
        delete (sanitized as any).phone;
      }
    }
    const user = new WxUser(sanitized);
    return await user.save();
  }

  /**
   * 根据手机号获取wxapp用户
   */
  async getWxUserByPhone(phone: string): Promise<IWxUser | null> {
    return await WxUser.findOne({ phone });
  }

  /**
   * 根据用户ID获取wxapp用户
   */
  async getWxUserById(id: string): Promise<IWxUser | null> {
    return await WxUser.findOne({ id });
  }

  /**
   * 根据微信openId获取wxapp用户
   */
  async getWxUserByOpenId(openId: string): Promise<IWxUser | null> {
    return await WxUser.findOne({ wechatOpenId: openId });
  }

  /**
   * 更新wxapp用户信息
   */
  async updateWxUser(id: string, updateData: Partial<IWxUser>): Promise<IWxUser | null> {
    const update: any = { ...updateData };
    // 如果传入了 phone 但为 null/空串，则改为 $unset
    if ('phone' in update) {
      const value = update.phone as any;
      if (value === null || value === undefined || (typeof value === 'string' && value.trim() === '')) {
        delete update.phone;
        update.$unset = { ...(update.$unset || {}), phone: '' };
      }
    }
    update.updatedAt = new Date();

    return await WxUser.findOneAndUpdate(
      { id },
      update,
      { new: true }
    );
  }

  /**
   * 获取所有wxapp用户
   */
  async getAllWxUsers(): Promise<IWxUser[]> {
    return await WxUser.find({}).select('-passwordHash');
  }

  // ========== wxapp RefreshToken 管理 ==========

  /**
   * 保存refreshToken
   */
  async saveWxRefreshToken(tokenData: Partial<IWxRefreshToken>): Promise<IWxRefreshToken> {
    const refreshToken = new WxRefreshToken(tokenData);
    return await refreshToken.save();
  }

  /**
   * 根据token获取refreshToken记录
   */
  async getWxRefreshToken(token: string): Promise<IWxRefreshToken | null> {
    return await WxRefreshToken.findOne({ 
      token,
      expiresAt: { $gt: new Date() } // 确保未过期
    });
  }

  /**
   * 删除refreshToken
   */
  async deleteWxRefreshToken(token: string): Promise<void> {
    await WxRefreshToken.deleteOne({ token });
  }

  /**
   * 删除用户的所有refreshToken
   */
  async deleteWxRefreshTokensByUserId(userId: string): Promise<void> {
    await WxRefreshToken.deleteMany({ userId });
  }

  /**
   * 清理过期的refreshToken
   */
  async cleanExpiredWxRefreshTokens(): Promise<void> {
    await WxRefreshToken.deleteMany({ 
      expiresAt: { $lt: new Date() } 
    });
  }

  // ========== OCR记录管理 ==========

  /**
   * 保存OCR处理记录
   */
  async saveOCRRecord(ocrData: Partial<IOCRRecord>): Promise<IOCRRecord> {
    const record = new OCRRecord({
      recordId: `ocr_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      ...ocrData
    });
    return await record.save();
  }

  /**
   * 获取用户的OCR历史记录
   */
  async getOCRHistory(userId: string, limit: number = 20): Promise<IOCRRecord[]> {
    return await OCRRecord.find({ userId })
      .sort({ createdAt: -1 })
      .limit(limit);
  }

  /**
   * 获取OCR统计信息
   */
  async getOCRStats(userId?: string): Promise<any> {
    const match = userId ? { userId } : {};
    
    const stats = await OCRRecord.aggregate([
      { $match: match },
      {
        $group: {
          _id: null,
          totalRecords: { $sum: 1 },
          successCount: { 
            $sum: { $cond: [{ $eq: ['$recognitionResult.success', true] }, 1, 0] } 
          },
          avgProcessingTime: { $avg: '$processingTime' },
          serviceTypeStats: {
            $push: '$serviceType'
          }
        }
      }
    ]);

    return stats[0] || {
      totalRecords: 0,
      successCount: 0,
      avgProcessingTime: 0,
      serviceTypeStats: []
    };
  }

  // ========== 医疗告警管理 ==========

  /**
   * 创建医疗告警
   */
  async createMedicalAlert(alertData: Partial<IMedicalAlert>): Promise<IMedicalAlert> {
    const alert = new MedicalAlert({
      alertId: `alert_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      ...alertData
    });
    return await alert.save();
  }

  /**
   * 获取医疗告警列表
   */
  async getMedicalAlerts(filters: {
    status?: string;
    priority?: string;
    type?: string;
    limit?: number;
  } = {}): Promise<IMedicalAlert[]> {
    const query: any = {};
    
    if (filters.status) query.status = filters.status;
    if (filters.priority) query.priority = filters.priority;
    if (filters.type) query.type = filters.type;

    return await MedicalAlert.find(query)
      .sort({ createdAt: -1 })
      .limit(filters.limit || 50);
  }

  /**
   * 解决告警
   */
  async resolveAlert(alertId: string, resolvedBy: string, resolutionNotes?: string): Promise<IMedicalAlert | null> {
    return await MedicalAlert.findOneAndUpdate(
      { alertId },
      {
        status: 'resolved',
        resolvedAt: new Date(),
        resolvedBy,
        resolutionNotes,
        updatedAt: new Date()
      },
      { new: true }
    );
  }

  /**
   * 获取告警统计
   */
  async getAlertStats(): Promise<any> {
    const stats = await MedicalAlert.aggregate([
      {
        $group: {
          _id: '$status',
          count: { $sum: 1 }
        }
      }
    ]);

    const priorityStats = await MedicalAlert.aggregate([
      { $match: { status: 'active' } },
      {
        $group: {
          _id: '$priority',
          count: { $sum: 1 }
        }
      }
    ]);

    return {
      byStatus: stats,
      byPriority: priorityStats
    };
  }

  // ========== 系统日志 ==========

  /**
   * 记录系统日志
   */
  async logAction(logData: Partial<ISystemLog>): Promise<ISystemLog> {
    const log = new SystemLog({
      logId: `log_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      ...logData
    });
    return await log.save();
  }

  /**
   * 获取系统日志
   */
  async getSystemLogs(filters: {
    userId?: string;
    level?: string;
    module?: string;
    limit?: number;
  } = {}): Promise<ISystemLog[]> {
    const query: any = {};
    
    if (filters.userId) query.userId = filters.userId;
    if (filters.level) query.level = filters.level;
    if (filters.module) query.module = filters.module;

    return await SystemLog.find(query)
      .sort({ createdAt: -1 })
      .limit(filters.limit || 100);
  }

  // ========== 医疗设备管理 ==========

  /**
   * 创建医疗设备
   */
  async createMedicalEquipment(equipmentData: Partial<IMedicalEquipment>): Promise<IMedicalEquipment> {
    const equipment = new MedicalEquipment({
      equipmentId: `eq_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      ...equipmentData
    });
    return await equipment.save();
  }

  /**
   * 获取医疗设备列表
   */
  async getMedicalEquipment(filters: {
    type?: string;
    status?: string;
    location?: string;
    limit?: number;
  } = {}): Promise<IMedicalEquipment[]> {
    const query: any = {};
    
    if (filters.type) query.type = filters.type;
    if (filters.status) query.status = filters.status;
    if (filters.location) query.location = { $regex: filters.location, $options: 'i' };

    return await MedicalEquipment.find(query)
      .sort({ name: 1 })
      .limit(filters.limit || 50);
  }

  /**
   * 更新设备状态
   */
  async updateEquipmentStatus(equipmentId: string, status: string): Promise<IMedicalEquipment | null> {
    return await MedicalEquipment.findOneAndUpdate(
      { equipmentId },
      { 
        status,
        updatedAt: new Date()
      },
      { new: true }
    );
  }

  // ========== 药品信息管理 ==========

  /**
   * 创建药品信息
   */
  async createDrugInfo(drugData: Partial<IDrugInfo>): Promise<IDrugInfo> {
    const drug = new DrugInfo({
      drugId: `drug_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      ...drugData
    });
    return await drug.save();
  }

  /**
   * 搜索药品信息
   */
  async searchDrugs(searchTerm: string, limit: number = 20): Promise<IDrugInfo[]> {
    return await DrugInfo.find({
      $or: [
        { name: { $regex: searchTerm, $options: 'i' } },
        { manufacturer: { $regex: searchTerm, $options: 'i' } },
        { category: { $regex: searchTerm, $options: 'i' } }
      ]
    })
    .sort({ name: 1 })
    .limit(limit);
  }

  /**
   * 获取即将过期的药品
   */
  async getExpiringDrugs(days: number = 30): Promise<IDrugInfo[]> {
    const expiryDate = new Date();
    expiryDate.setDate(expiryDate.getDate() + days);

    return await DrugInfo.find({
      expiryDate: { $lte: expiryDate, $gte: new Date() }
    })
    .sort({ expiryDate: 1 });
  }

  // ========== 数据迁移和同步 ==========

  /**
   * 从内存数据库同步用户到MongoDB
   */
  async syncUsersFromMemory(memoryUserDb: Map<string, any>): Promise<void> {
    console.log('[MongoDB] 开始同步用户数据...');
    
    for (const [userId, userData] of memoryUserDb.entries()) {
      try {
        // 检查用户是否已存在
        const existingUser = await User.findOne({ userId });
        
        if (!existingUser) {
          // 创建新用户
          const newUser = new User({
            userId,
            username: userData.username,
            password: userData.password,
            email: userData.email,
            role: userData.role,
            createdAt: new Date(userData.created_at),
            hasFace: userData.has_face || false
          });
          
          await newUser.save();
          console.log(`[MongoDB] 同步用户: ${userData.username}`);
        } else {
          // 更新现有用户
          await User.updateOne(
            { userId },
            {
              hasFace: userData.has_face || false,
              role: userData.role
            }
          );
        }
      } catch (error) {
        console.error(`[MongoDB] 同步用户 ${userData.username} 失败:`, error);
      }
    }
    
    console.log('[MongoDB] 用户数据同步完成');
  }

  /**
   * 从face_data.json同步人脸数据
   */
  async syncFaceDataFromFile(faceDataPath: string): Promise<void> {
    try {
      const fs = await import('fs');
      if (!fs.existsSync(faceDataPath)) {
        console.log('[MongoDB] 人脸数据文件不存在，跳过同步');
        return;
      }

      const faceData = JSON.parse(fs.readFileSync(faceDataPath, 'utf-8'));
      
      for (const [username, data] of Object.entries(faceData)) {
        const faceInfo = data as { name: string; hash: string; timestamp: string };
        
        await User.updateOne(
          { username },
          {
            hasFace: true,
            faceData: {
              hash: faceInfo.hash,
              timestamp: new Date(faceInfo.timestamp)
            }
          }
        );
        
        console.log(`[MongoDB] 同步人脸数据: ${username}`);
      }
      
      console.log('[MongoDB] 人脸数据同步完成');
    } catch (error) {
      console.error('[MongoDB] 同步人脸数据失败:', error);
    }
  }
}

// 导出单例实例
export const mongoDBService = new MongoDBService();

// ========== 患者管理 ==========
export class PatientService {
  async createPatient(data: Partial<IPatient>): Promise<IPatient> {
    const patient = new Patient(data);
    return await patient.save();
  }

  async getPatientByOpenId(openid: string): Promise<IPatient | null> {
    return await Patient.findOne({ openid });
  }

  async getPatientByPhone(phone: string): Promise<IPatient | null> {
    return await Patient.findOne({ phone });
  }

  async getPatientById(patientId: string): Promise<IPatient | null> {
    return await Patient.findOne({ patientId });
  }

  async updatePatient(patientId: string, update: Partial<IPatient>): Promise<IPatient | null> {
    return await Patient.findOneAndUpdate({ patientId }, update, { new: true });
  }
}

export const patientService = new PatientService();